package com.zl.rbac.web.advice;

import com.zl.rbac.VO.ResultCode;
import com.zl.rbac.VO.ResultVO;
import com.zl.rbac.exception.NoPermissionException;
import com.zl.rbac.exception.RbacException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

	@ExceptionHandler(value=Exception.class)
	@ResponseBody
	public Object defaultExceptionHandler(HttpServletRequest req, HandlerMethod handlerMethod, Exception e) {
		//handlerMethod 得到请求的处理器方法对象, 判断这个方法的返回的是否是逻辑视图,还是json数据
		//1.判断请求的Controller上是否标记 @RestController, 获取这个Controller类使用标记@ResponseBody注解
		// 获取这个方法上是否标记@ResponseBody注解, 表示请求方法响应的数据
		Class clazz = handlerMethod.getBeanType();
		boolean isRest = clazz.isAnnotationPresent(RestController.class) || clazz.isAnnotationPresent(ResponseBody.class)
				|| handlerMethod.getMethod().isAnnotationPresent(ResponseBody.class);

		//2.判断请求是否是一个Ajax请求, 响应的数据
		if (isRest || isAjax(req)) {
			//响应数据
			if (e instanceof NoPermissionException) {  //处理的是一个没有权限的异常
				return new ResultVO<String>(ResultCode.NO_PERMISSION_FAILED, e.getMessage());
			} else if (e instanceof RbacException) {
				return new ResultVO<String>(ResultCode.ERROR, e.getMessage());
			} else{
				return new ResultVO<String>(ResultCode.ERROR, "系统忙,请稍后再试!!!");
			}
		}
		//响应的视图
		//该视图一定使用ModelAndView对象来设置, 该方法上添加@ResponseBody, 但是SpringMVC后台检查到返回的
		//ModelAndView对象,不会作为数据返回, 解析为视图
		ModelAndView modelAndView = new ModelAndView();
		if (e instanceof NoPermissionException) {  //处理的是一个没有权限的异常
			//modelAndView.addObject()
			modelAndView.setViewName("main/noPermissionError");
		} else if (e instanceof RbacException) {
			modelAndView.addObject("errorMessage", e.getMessage());
			modelAndView.setViewName("main/error");
		} else if (e instanceof Exception) {
			modelAndView.addObject("errorMessage", "系统忙,请稍后再试!!!");
			modelAndView.setViewName("main/error");
		}
		return modelAndView;
	}

	public boolean isAjax(HttpServletRequest req){
		String accept = req.getHeader("accept");  //application/json
		String  requestWith = req.getHeader("X-Requested-With");  //XMLHttpRequest
		if((accept!=null && accept.contains("application/json"))
				|| (requestWith!=null && requestWith.equalsIgnoreCase("XMLHttpRequest"))
				){
			return true;
		}
		return  false;
	}
}